package org.jeecg.glr.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.glr.entity.*;
import org.jeecg.glr.mapper.*;
import org.jeecg.glr.service.IGlrVideoBdService;
import org.jeecg.glr.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: 海康摄像头
 * @Author: jeecg-boot
 * @Date:   2020-02-11
 * @Version: V1.0
 */
@Service
public class GlrVideoBdServiceImpl extends ServiceImpl<GlrVideoBdMapper, GlrVideoBd> implements IGlrVideoBdService {

    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;

    @Autowired
    private GlrVideoBdUserMapper glrVideoBdUserMapper;

    @Autowired
    private GlrVideoYsMapper glrVideoYsMapper;

    @Autowired
    private GlrVideoBdRecognizeMapper glrVideoBdRecognizeMapper;

    @Autowired
    private GlrVideoBdURRelationMapper glrVideoBdURRelationMapper;

    @Autowired
    private GlrVideoMapper glrVideoMapper;


    public String getToken(GlrVideoBd entity){
        String stToken = "";
        if(entity.getExpirationDate() == null
                || entity.getExpirationDate().getTime() < DateUtils.getDateAddMinuteTime(10).getTime()){
            //需要重新取token
            try{
                String stappKey = entity.getAppKey();
                String stsercetKey = entity.getSercetKey();
                String url = HttpRequestUtil.BAIDU_TOKEN_URL.replaceAll("APPKEY", stappKey).replaceAll("APPSECRET",
                        stsercetKey);
                com.alibaba.fastjson.JSONObject json = HttpRequestUtil.httpRequest(url, "POST", null);
                //JSONObject json = JSONObject.fromObject("{\"msg\":\"操作成功!\",\"code\":\"200\",\"data\":{\"expireTime\":1558935170465,\"accessToken\":\"at.al61q67n10193ssf1u7w3xff15jb3bha-5mlmjssash-0zvvncb-j98ftbzjp\"}}");
                String accessToken = json.get("access_token").toString();
                Integer expires_in = Integer.valueOf(json.get("expires_in").toString());
                //System.out.println("expires_in:" + expires_in);

                Calendar c = Calendar.getInstance();
                //System.out.println("现在日期：" + c.get(c.YEAR) + "/" + c.get(c.MONTH) + "/" + c.get(c.DAY_OF_MONTH));
                c.add(13, expires_in.intValue());
                //System.out.println("过期日期：" + c.get(c.YEAR) + "/" + c.get(c.MONTH) + "/" + c.get(c.DAY_OF_MONTH));
                Calendar expireDate  = c;

                GlrVideoBd glrVideoBd = super.getById(entity.getId());
                glrVideoBd.setToken(accessToken);
                glrVideoBd.setExpirationDate(c.getTime());
                super.saveOrUpdate(glrVideoBd);

            }catch (Exception ex){
                //	System.out.println(ex.getMessage());
                GlrVideoBd glrVideoBd = super.getById(entity.getId());
                glrVideoBd.setToken("");
                glrVideoBd.setExpirationDate(null);
                super.saveOrUpdate(glrVideoBd);
            }
            entity = super.getById(entity.getId());
        }
        stToken = entity.getToken();
        return stToken;
    }

    public String getToken(String videoBdId){
        GlrVideoBd entity = super.getById(videoBdId);
        return getToken(entity);
    }

    public void doUpdateUserInfo(String ids)  throws Exception{
        //String str[] = ids.split(",");
        JSONObject j1=JSONObject.parseObject(ids);
        String str[]=j1.get("ids").toString().split(",");
        String ctxPath = uploadpath;
        String bizPath = GLRConstant.FILE_PATH_FACE;//根据业务名称判断上传路径

        for (String id : str) {

            GlrVideoBdUser glrVideoBdUser = glrVideoBdUserMapper.selectById(id);
            if (glrVideoBdUser!=null) {
                String baiduServerCode=glrVideoBdUser.getBaiduServerCode();
                if (StringUtil.isNotEmpty(baiduServerCode)) {
                    QueryWrapper<GlrVideoBd> queryWrapper = new QueryWrapper<GlrVideoBd>();
                    queryWrapper.eq("code", baiduServerCode);
                    GlrVideoBd glrVideoBd=super.getOne(queryWrapper);
                    glrVideoBdUser.setGlrVideoBd(glrVideoBd);
                }else throw new Exception("找不到服务器");
                List<Map<String, Object>> resourcesIdList=glrVideoYsMapper.doGetListForJdbc("select a.file_path,b.id from glr_video_bd_resource a\n" +
                        "left join glr_video_bd_u_r_relation b on a.id=b.resource_id\n" +
                        "where b.user_id='"+glrVideoBdUser.getId()+"'");

                if (resourcesIdList.size()==0) throw new Exception("找不到图片");
                boolean bfirst=true;
                for (Map<String, Object> map1:resourcesIdList){
                    //20190918_glradmin\1568795919402_微信图片_20190917103741.jpg
                    String st1=map1.get("file_path").toString();
                    String stid=map1.get("id").toString();

                    String st2=ctxPath + File.separator +st1;



                    String str11 = Base64Util.ImageToBase64ByLocal(st2);

                    Map<String, Object> map = new HashMap<>();
                    //图片类型
                    //BASE64:图片的base64值，base64编码后的图片数据，编码后的图片大小不超过2M；
                    //URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长)；
                    //FACE_TOKEN：人脸图片的唯一标识，调用人脸检测接口时，会为每个人脸图片赋予一个唯一的FACE_TOKEN，同一张图片多次检测得到的FACE_TOKEN是同一个。
                    map.put("image_type", "BASE64");
                    //图片信息(总数据大小应小于10M)，图片上传方式根据image_type来判断。
                    //注：组内每个uid下的人脸图片数目上限为20张
                    map.put("image", str11);
                    //用户组id，标识一组用户（由数字、字母、下划线组成），长度限制48B。产品建议：根据您的业务需求，可以将需要注册的用户，按照业务划分，分配到不同的group下，
                    // 例如按照会员手机尾号作为groupid，用于刷脸支付、会员计费消费等，这样可以尽可能控制每个group下的用户数与人脸数，提升检索的准确率
                    map.put("group_id", HttpRequestUtil.BAIDU_USER_GROUP_ID);
                    //用户id（由数字、字母、下划线组成），长度限制128B
                    map.put("user_id", glrVideoBdUser.getCode());
                    //用户资料，长度限制256B 默认空
                    map.put("user_info", glrVideoBdUser.getName());
                    //活体检测控制
                    //NONE: 不进行控制
                    //LOW:较低的活体要求(高通过率 低攻击拒绝率)
                    //NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率)
                    //HIGH: 较高的活体要求(高攻击拒绝率 低通过率)
                    //默认NONE
                    //若活体检测结果不满足要求，则返回结果中会提示活体检测失败
                    map.put("liveness_control", "NORMAL");
                    //图片质量控制
                    //NONE: 不进行控制
                    //LOW:较低的质量要求
                    //NORMAL: 一般的质量要求
                    //HIGH: 较高的质量要求
                    //默认 NONE
                    //若图片质量不满足要求，则返回结果中会提示质量检测失败
                    map.put("quality_control", "LOW");
                    //APPEND: 当user_id在库中已经存在时，对此user_id重复注册时，新注册的图片默认会追加到该user_id下
                    //REPLACE : 当对此user_id重复注册时,则会用新图替换库中该user_id下所有图片
                    //默认使用APPEND
                    if (bfirst){
                        map.put("action_type", "REPLACE");
                        bfirst=false;
                    }else{
                        map.put("action_type", "APPEND");
                    }


                    String param = GsonUtils.toJson(map);



                    // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
                    String accessToken = getToken(glrVideoBdUser.getGlrVideoBd());
                    String result = org.jeecg.glr.util.HttpUtil.post(HttpRequestUtil.BAIDU_USER_ADD_URL, accessToken, "application/json", param);

                    ObjectMapper objectMapper = new ObjectMapper();
                    JSONObject jsonObject = objectMapper.readValue(result, JSONObject.class);

                    //"result" -> " size = 2"
                    if (jsonObject.get("error_code").toString().equals("0")){
                        JSONObject jsonObject1 = (JSONObject)jsonObject.get("result");
                        //face_token
                        String stface_token=jsonObject1.get("face_token").toString();

                        //stid
                        GlrVideoBdURRelation glrVideoBdURRelation=glrVideoBdURRelationMapper.selectById(stid);
                        glrVideoBdURRelation.setFaceToken(stface_token);
                        glrVideoBdURRelationMapper.updateById(glrVideoBdURRelation);
                    }
                    //System.out.println(result);
                }
            }
        }
    }

    public void doPhotoMatch(GlrVideoBdRecognize entity, String fileBase64)  throws Exception{
        try{
            String baiduServerCode=entity.getBaiduServerCode();
            if (StringUtil.isNotEmpty(baiduServerCode)) {
                QueryWrapper<GlrVideoBd> queryWrapper = new QueryWrapper<GlrVideoBd>();
                queryWrapper.eq("code", baiduServerCode);
                GlrVideoBd glrVideoBd=super.getOne(queryWrapper);
                entity.setGlrVideoBd(glrVideoBd);
            }else throw new Exception("找不到服务器");
            Map<String, Object> map = new HashMap<>();
            //图片类型
            //BASE64:图片的base64值，base64编码后的图片数据，编码后的图片大小不超过2M；
            //URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长)；
            //FACE_TOKEN：人脸图片的唯一标识，调用人脸检测接口时，会为每个人脸图片赋予一个唯一的FACE_TOKEN，同一张图片多次检测得到的FACE_TOKEN是同一个。
            map.put("image_type", "BASE64");
            //图片信息(总数据大小应小于10M)，图片上传方式根据image_type来判断。
            //注：组内每个uid下的人脸图片数目上限为20张
            map.put("image", fileBase64);
            map.put("liveness_control", "NORMAL");
            map.put("group_id_list", HttpRequestUtil.BAIDU_USER_GROUP_ID);
            map.put("quality_control", "LOW");
            String param = GsonUtils.toJson(map);
            String accessToken = getToken(entity.getGlrVideoBd());
            String result = org.jeecg.glr.util.HttpUtil.post(HttpRequestUtil.BAIDU_USER_FACE_SEARCH, accessToken, "application/json", param);
            ObjectMapper objectMapper = new ObjectMapper();
            JSONObject jsonObject = objectMapper.readValue(result, JSONObject.class);
            String stface_token="";

            if (jsonObject.get("error_code").toString().equals("0")){
                JSONObject jsonObject1 = (JSONObject)jsonObject.get("result");
                stface_token=jsonObject1.get("face_token").toString();
                JSONArray jsonArray=jsonObject1.getJSONArray("user_list");
                double dd1=0;
                String st11="",st12="",st13="";
                for(int i=0;i<jsonArray.size();i++){
                    JSONObject job = jsonArray.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                    double d1=job.getDouble("score");
                    String stuser_id=job.get("user_id").toString();
                    String stgroup_id=job.get("group_id").toString();
                    String stuser_info=job.get("user_info").toString();
                    BigDecimal data1 = new BigDecimal(dd1);
                    BigDecimal data2 = new BigDecimal(d1);
                    if (data2.compareTo(data1)>0){
                        st11=stuser_id;
                        st12=stgroup_id;
                        st13=stuser_info;
                        dd1=d1;
                    }
                }

                BigDecimal data1 = new BigDecimal(dd1);
                if (data1.compareTo(new BigDecimal(0))>0){
                    entity.setScore(dd1);
                    entity.setUserId(st11);
                    entity.setGroupId(st12);
                    entity.setUserInfo(st13);
                }
            }else{
                String sterror_code=jsonObject.get("error_code").toString();
                String sterror_msg=jsonObject.get("error_msg").toString();
                entity.setError_code(sterror_code);
                entity.setError_msg(sterror_msg);
            }

            map = new HashMap<>();
            if (StringUtil.isNotEmpty(stface_token)){
                map.put("image", stface_token);
                map.put("image_type", "FACE_TOKEN");
            }else{
                map.put("image_type", "BASE64");
                map.put("image", fileBase64);
            }
            map.put("face_field", "age,beauty,expression,faceshape,gender,glasses,landmark,race,qualities,eye_status,emotion");
            map.put("max_face_num", 1);
            param = GsonUtils.toJson(map);
            result = org.jeecg.glr.util.HttpUtil.post(HttpRequestUtil.BAIDU_FACE_DETECT, accessToken, "application/json", param);
            objectMapper = new ObjectMapper();
            jsonObject = objectMapper.readValue(result, JSONObject.class);
            if ("0".equals(jsonObject.getString("error_code"))){
                JSONObject jsonObject11=jsonObject.getJSONObject("result");
                JSONArray face_list=(JSONArray)jsonObject11.get("face_list");
                if (face_list.size()>0){
                    JSONObject jsonObject12=(JSONObject)face_list.get(0);
                    entity.setFace_detect(jsonObject12.toString());
                }
            }
            //String st1=redisService.getString(entity.getEquipmentSerial());
            RedisUtil redisService=new RedisUtil();
            Object ob1=redisService.get(GLRConstant.VIDEO_CODE_REDIS+"_"+entity.getEquipmentSerial());
            if (ob1==null){
                //TBVideo tBVideo=super.findUniqueByProperty(TBVideo.class, "equipmentSerial", entity.getEquipmentSerial());
                QueryWrapper<GlrVideo> queryWrapper = new QueryWrapper<GlrVideo>();
                queryWrapper.eq("equipmentSerial", entity.getEquipmentSerial());
                GlrVideo glrVideo=glrVideoMapper.selectOne(queryWrapper);

                if (glrVideo!=null){
                    String code=glrVideo.getSysCompanyCode();
                    redisService.set(GLRConstant.VIDEO_CODE_REDIS+"_"+glrVideo.getEquipmentSerial(),code);
                }
            }
            String st1=ob1.toString();
            entity.setSysCompanyCode(st1);
            entity.setSysOrgCode(st1);
            entity.setCreateTime(new Date());
            glrVideoBdRecognizeMapper.updateById(entity);


        }catch (Exception ex){

        }

    }
}
